package com.daffodil.workable.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.daffodil.core.dao.JpaDao;
import com.daffodil.core.entity.Query;
import com.daffodil.core.exception.BaseException;
import com.daffodil.workable.constant.WorkableConstant;
import com.daffodil.workable.entity.WorkablePlan;
import com.daffodil.workable.service.IWorkablePlanService;
import com.daffodil.workable.util.WorkableUtils;
import com.daffodil.util.HqlUtils;
import com.daffodil.util.StringUtils;

/**
 * -执行计划Service接口业务实现层
 * @author yweijian
 * @date 2022-04-28
 * @version 1.0
 * @description
 */
@Service
public class WorkablePlanServiceImpl implements IWorkablePlanService {

    @Autowired
    private JpaDao<String> jpaDao;

    @Override
    public List<WorkablePlan> selectWorkablePlanList(Query<WorkablePlan> query) {
        StringBuffer hql = new StringBuffer("select new WorkablePlan(p.id, p.planName, p.taskId, t.taskName, concat(t.major, '.', t.minor, '.', t.patch, '.', t.build), p.status, p.expression, p.orderNum, p.lastTime, p.nextTime, p.createBy, p.createTime, p.updateBy, p.updateTime, p.remark) ");
        hql.append("from WorkablePlan p left join WorkableTask t on t.id = p.taskId where 1=1 ");
        List<Object> paras = new ArrayList<Object>();
        HqlUtils.createHql(hql, paras, query, "p");
        return jpaDao.search(hql.toString(), paras, WorkablePlan.class, query.getPage());
    }

    @Override
    public WorkablePlan selectWorkablePlanById(String id) {
        return jpaDao.find(WorkablePlan.class, id);
    }

    @Override
    @Transactional
    public void insertWorkablePlan(WorkablePlan workablePlan) {
        if(!WorkableUtils.isValidExpression(workablePlan.getExpression())) {
            throw new BaseException(60001);
        }
        workablePlan.setStatus(WorkableConstant.WORKABLE_SHUTDOWN);
        workablePlan.setLastTime(0L);
        workablePlan.setNextTime(0L);
        jpaDao.save(workablePlan);
    }

    @Override
    @Transactional
    public void updateWorkablePlan(WorkablePlan workablePlan) {
        if(!WorkableUtils.isValidExpression(workablePlan.getExpression())) {
            throw new BaseException(60001);
        }
        jpaDao.update(workablePlan);
    }

    @Override
    @Transactional
    public void deleteWorkablePlanByIds(String[] ids) {
        if(StringUtils.isNotEmpty(ids)) {
            for(String id : ids) {
                WorkablePlan plan = jpaDao.find(WorkablePlan.class, id);
                if(StringUtils.isNotNull(plan) && WorkableConstant.WORKABLE_STARTUP.equals(plan.getStatus())) {
                    throw new BaseException(60002);
                }
                jpaDao.delete(plan);
            }
        }
    }

    @Override
    @Transactional
    public void stratupWorkablePlanByIds(String[] ids) {
        if(StringUtils.isNotEmpty(ids)) {
            for(String id : ids) {
                WorkablePlan plan = jpaDao.find(WorkablePlan.class, id);
                if(StringUtils.isNotNull(plan) && StringUtils.isNotEmpty(plan.getExpression())) {
                    long nextTime = WorkableUtils.getNextTriggerTime(plan.getExpression(), new Date());
                    plan.setStatus(nextTime <= 0 ? WorkableConstant.WORKABLE_SHUTDOWN : WorkableConstant.WORKABLE_STARTUP);
                    plan.setNextTime(nextTime);
                }
            }
        }
    }

    @Override
    @Transactional
    public void shutdownWorkablePlanByIds(String[] ids) {
        if(StringUtils.isNotEmpty(ids)) {
            for(String id : ids) {
                WorkablePlan plan = jpaDao.find(WorkablePlan.class, id);
                if(StringUtils.isNotNull(plan)){
                    plan.setStatus(WorkableConstant.WORKABLE_SHUTDOWN);
                    plan.setNextTime(0L);
                    jpaDao.update(plan);
                }
            }
        }
    }

}
